# modules/common/apk_installer.py
import subprocess, pathlib, logging, re

_PKG_PATTERN = re.compile(r'package:\s+name=\'([^\']+)')

def _get_installed_pkgs(device: str):
    adb = ["adb"]
    if device:
        adb += ["-s", device]
    out = subprocess.check_output(adb + ["shell", "pm", "list", "packages"],
                                  text=True)
    return {line.split(':')[-1].strip() for line in out.splitlines() if line}

def install_all(apk_dir: str, device: str = "",
                skip_if_installed: bool = True):
    """
    遍历 apk_dir 下所有 .apk 文件并安装；可选跳过已装包。
    """
    # 检查APK目录是否存在
    apk_path = pathlib.Path(apk_dir)
    if not apk_path.exists():
        logging.error(f"APK 目录不存在: {apk_dir}")
        return
    
    adb_base = ["adb"] + (["-s", device] if device else [])
    
    try:
        installed = _get_installed_pkgs(device) if skip_if_installed else set()
    except Exception as e:
        logging.error(f"获取已安装应用列表失败: {e}")
        installed = set()

    apk_files = list(apk_path.rglob("*.apk"))
    if not apk_files:
        logging.warning(f"APK 目录中没有找到 APK 文件: {apk_dir}")
        return
    
    logging.info(f"找到 {len(apk_files)} 个 APK 文件")
    
    for apk in apk_files:
        # 用 aapt/apt2 提取包名；若工具缺失则直接 adb install -r
        pkg = _extract_pkgname(apk) or apk.stem
        if skip_if_installed and pkg in installed:
            logging.info("已安装，跳过 %s (%s)", apk.name, pkg)
            continue

        cmd = adb_base + ["install", "-r","-g", str(apk)]
        logging.info("installing %s …", apk.name)
        try:
            out = subprocess.check_output(cmd, stderr=subprocess.STDOUT,
                                          text=True, timeout=180)
            logging.info("%s 安装成功：%s", apk.name,
                         out.strip().splitlines()[-1])
        except subprocess.TimeoutExpired:
            logging.error("安装超时 %s", apk.name)
        except subprocess.CalledProcessError as e:
            logging.error("安装失败 %s：%s", apk.name, e.output.strip())
        except Exception as e:
            logging.error("安装过程中出现异常 %s：%s", apk.name, e)

def _extract_pkgname(apk_path: pathlib.Path):
    """尝试用 aapt2/bundletool 获取包名；失败返回 None"""
    import shutil, json, tempfile, os
    aapt = shutil.which("aapt") or shutil.which("aapt2")
    if not aapt:
        return None
    try:
        out = subprocess.check_output([aapt, "dump", "badging", str(apk_path)],
                                      text=True, timeout=30, stderr=subprocess.DEVNULL)
        m = re.search(r"package: name='([^']+)'", out)
        return m.group(1) if m else None
    except Exception:
        return None
